package myky.com.doctorapp.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import myky.com.doctorapp.R;
import myky.com.doctorapp.api.Address;
import myky.com.doctorapp.entity.ImageEntity;

import myky.com.doctorapp.entity.UploadResultEntity;
import myky.com.doctorapp.contract.ImageUploadContract;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;

/**
 * Description:图片上传工具类
 *
 * @author wuyangwuyang
 * Created by 2019/3/5 on 11:06
 */
public class ImageUtils {

    /**
     * 设置连接超时时间
     */
    private final static int CONNECT_TIMEOUT = 60;
    /**
     * 设置读取超时时间
     */
    private final static int READ_TIMEOUT = 120;
    /**
     * 设置写的超时时间
     */
    private final static int WRITE_TIMEOUT = 120;
    /**
     * 设置连接超时时间
     */
    private static OkHttpClient httpClient= new OkHttpClient().newBuilder().connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            //设置读取超时时间
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            //设置写的超时时间
            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
            .build();
    private static MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
    private static MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
    /**
     * 要求按加入顺序遍历输出
     */
    public static HashMap<Integer, String> hashMap;
    private static ImageUploadContract uploadOnListeners;
    private static List<ImageEntity> imglist;
    private static ArrayList<String> stringmd5;
    private static Context context;
    private static boolean allNetImg=true;

    private static final int RESULT_ERROR = 1000;
    private static final int RESULT_SUCCESS = 2000;
    @SuppressLint("HandlerLeak")
    private static Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
                    switch (msg.what){

                        case RESULT_SUCCESS:
                            ArrayList<String> list = msg.getData().getStringArrayList(Constants.IMAGELIST);
                            uploadOnListeners.uploadSuccess(list);
                            break;
                        case RESULT_ERROR:
                            uploadOnListeners.uploadFail(msg.obj.toString());
                            break;
                        default:
                            break;
                    }
        }
    };
    public static void upload(Context contexts,List<ImageEntity> entityList,ImageUploadContract uploadOnListener){

        context=contexts;
        uploadOnListeners=uploadOnListener;
        imglist=new ArrayList<>();
        stringmd5=new ArrayList<>();
        imglist.addAll(entityList);
//        将不需要上传的图片分离出来(添加照片按钮路径为空)
        for (int i = 0; i < imglist.size(); i++) {
        if (TextUtils.isEmpty(imglist.get(i).getPath())){
           imglist.remove(i);
        }
        }
        if (imglist.size()==0){
            uploadOnListeners.uploadFail(context.getResources().getString(R.string.image_upload_hint));
            return;
        }
        hashMap=new HashMap<>(imglist.size());
//        判断是本地图片还是已上传的网络图片
        for (int i = 0; i < imglist.size(); i++) {
            String imagePath = imglist.get(i).getPath();
            if (imglist.get(i).isIs_md5()){
                hashMap.put(i,imagePath);
            }else {
//                是否全部都是病历图片
                allNetImg=false;
                compressPhoto(i,imagePath);
            }
        }
//        如果全部都是病历图片直接上传
        if (allNetImg){
            for (int i = 0; i < imglist.size(); i++) {
                stringmd5.add(hashMap.get(i));
            }
            uploadOnListener.uploadSuccess(stringmd5);

        }    }

    /**
     * 压缩本地图片
     * @param index
     * @param imagePath
     */
    private static void compressPhoto(int index, String imagePath) {
        Luban.with(context)
                // 传人要压缩的图片列表(包括file，path，List<String>)
                .load(imagePath)
                // 忽略不压缩图片的大小
                .ignoreBy(100)
                //设置目标文件夹
                .setCompressListener(new OnCompressListener() {
                    @Override
                    public void onStart() {
                        // TODO 压缩开始前调用，可以在方法内启动 loading UI
                        Log.d("luban", "使用鲁班IO模式压缩,开始压缩");
                    }

                    @Override
                    public void onSuccess(File file) {
                        // TODO 压缩成功后调用，返回压缩后的图片文件
                        uploadImage(file.getAbsolutePath(), index);
                        Log.i("output", "第" + index + "张图片压缩成功,开始上传");
                    }

                    @Override
                    public void onError(Throwable e) {
                        // TODO 当压缩过程出现问题时用原图上传
                        uploadImage(imagePath, index);
                        Log.i("output", "第" + index + "张图片压缩失败,使用原图片上传");
                    }
                }).launch(); //启动压缩
    }

    /**
     * 图片上传
     */
    private static void uploadImage(String path,int index){

        httpClient = new OkHttpClient();
        File f = new File(path);
        if (f != null) {
            builder.addFormDataPart("file", f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
        }
        MultipartBody requestBody = builder.build();
        //构建请求
        Request request = new Request.Builder()
                //地址
                .url(Address.IMAGEUPLOADURL)
                //添加请求体
                .post(requestBody)
                .build();
        httpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Message message = handler.obtainMessage();
                message.what = RESULT_ERROR;
                message.obj = context.getResources().getString(R.string.net_exception);
                message.sendToTarget();

            }

            @Override
            public void onResponse(Call call, Response response){
                try {
                String result = response.body().string();
                Gson gson = new Gson();
                UploadResultEntity UploadResultEntity = gson.fromJson(result, UploadResultEntity.class);
                if (UploadResultEntity.getCode() == 0 && !UploadResultEntity.getData().equals("")) {
                    hashMap.put(index, UploadResultEntity.getData());
                    isSuccessAll();
                }
                }catch (Exception e){
                    Message message = handler.obtainMessage();
                    message.what = RESULT_ERROR;
                    message.obj = context.getResources().getString(R.string.service_exception);
                    message.sendToTarget();
                }
            }
        });

    }

    /**
     * 判断是否全部上传成功
     */
    private static void isSuccessAll() {

        if (hashMap.size() == imglist.size() && hashMap.size() > 0) {
            //将保存到map根据对应的下标设置MD5值
            for (int i = 0; i < hashMap.size(); i++) {
                stringmd5.add(hashMap.get(i));
            }
            Message message = handler.obtainMessage();
            message.what = RESULT_SUCCESS;
            Bundle bundle=new Bundle();
            bundle.putStringArrayList(Constants.IMAGELIST,stringmd5);
            message.setData(bundle);
            message.sendToTarget();
        }
    }
}
